#ifndef _VGA_H_
#define _VGA_H_
#include <string.h>
#include <stdlib.h>

#define MAX_SCREEN_DATA_SIZE        16000

#define VGA_DEFAULT_TEXT_MEM    0xB8000
#define VGA_DEFAULT_TEXT_WIDTH  80
#define VGA_DEFAULT_TEXT_HEIGHT 25
#define VGA_DEFAULT_ATTR        0x7

#define VGA_DATA_ACTIVE         (1 << 0)

#define VGA_TEXT_CURSOR_H       0x0E
#define VGA_TEXT_CURSOR_L       0x0F

#define VGA_REG_ADDR            0x03D4
#define VGA_REG_DATA            0x03D5

#define VGA_TEXT_CR             '\r'
#define VGA_TEXT_LF             '\n'
#define VGA_TEXT_BACK           '\x8'

#define VGA_TEXT_STR_CRLF       "\r\n"

#define VGA_TEXT_MODE_STR       0
#define VGA_TEXT_MODE_RAW       1
#define VGA_MEM_MODE_STR        2
#define VGA_MEM_MODE_RAW        3

#define VGA_IOCTL_SHOW          1
#define VGA_IOCTL_FLUSH         2
#define VGA_IOCTL_CLEAR         3

#define ISCURRENTSCR(s) (((currentscr *)NODE_HEAD(s))->current == s)

typedef struct {
    link_node node;
    int mode;
    int flag;
    char scrdata[MAX_SCREEN_DATA_SIZE];
    point cursor;
    int base;
    char default_attr;
    point size;
} screen;

typedef struct {
    link_node head;
    screen * current;
} currentscr;

void vga_out_mem_ch(screen * scr, int pos, char c);

void vga_out_mem_wch(screen * scr, int pos, char c, char attr);

void vga_out_mem_str(screen * scr, int pos, char * s, size_t l);

void vga_out_mem_wstr(screen * scr, int pos, char * s, size_t l);

char vga_in_mem_ch(screen * scr, int pos);

short vga_in_mem_wch(screen * scr, int pos);

void vga_in_mem_str(screen * scr, int pos, char * s, size_t l);

void vga_in_mem_wstr(screen * scr, int pos, char * s, size_t l);

void vga_out_ch(screen * scr, char c);

void vga_out_ch_attr(screen * scr, char c, char attr);

void vga_out_str(screen * scr, char * s, size_t l);

void vga_out_str_attr(screen * scr, char * s, size_t l);

void vga_text_init();

void vga_text_clear(screen * scr);

void vga_text_roll(screen * scr, int n);

void vga_text_set_cursor_pos(screen * scr, char x, char y);

void vga_text_get_cursor_pos(screen * scr, char * x, char * y);

void vga_text_flush();

void * vga_text_open(void * handle, int mode, int flag);

int vga_text_close(void * handle);

ssize_t vga_text_read(void * handle, char * bfr, size_t n);

ssize_t vga_text_write(void * handle, char * bfr, size_t n);

int vga_text_ioctl(void * handle, int mode, void * arg);

#endif _VGA_H_ /* end of _VGA_H_ */
